home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
CBGRX100.ARJ
/
BESTFONT.C
< prev
next >
Wrap
Text File
|
1992-04-10
|
5KB
|
188 lines
/**
** BESTFONT.C
**
** Copyright (C) 1992, Csaba Biegl
** 820 Stirrup Dr, Nashville, TN, 37221
** csaba@vuse.vanderbilt.edu
**
** This file is distributed under the terms listed in the document
** "copying.cb", available from the author at the address above.
** A copy of "copying.cb" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.cb".
** You should also have received a copy of the GNU General Public
** License along with this program (it is in the file "copying");
** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
** Cambridge, MA 02139, USA.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**/
#include "grx.h"
#include "libgrx.h"
#include "grxfile.h"
#include "gmalloc.h"
#include <string.h>
#include <stdio.h>
#include <io.h>
#define FNT_USABLE fnt_internal /* reuse this flag ! */
static GrFont *fontDB;
static int DBsize;
static int loaded = FALSE;
static int load_fontDB(void)
{
FntDirHdr hdr;
char fullname[200];
int file,size;
_GrGetFname("fonts.dir",_GrFontPath,FNTENV,"",fullname);
if((file = _GrFileOpen(fullname)) == EOF) return(FALSE);
if((read(file,&hdr,sizeof(FntDirHdr)) != sizeof(FntDirHdr)) ||
(hdr.magic != FONTDIR_MAGIC) ||
((size = sizeof(GrFont) * (int)hdr.numentries) <= 0) ||
((fontDB = _GrMalloc(size)) == NULL) ||
(read(file,fontDB,size) != size)) {
if(fontDB != NULL) _GrFree(fontDB);
_GrFileClose(file);
return(FALSE);
}
_GrFileClose(file);
DBsize = (int)hdr.numentries;
return(loaded = TRUE);
}
static int match_aux(char *pattern,char *string)
{
for( ; ; ) {
switch(*pattern) {
case '\0':
case ':':
return((*string == '\0') ? TRUE : FALSE);
case '?':
if(*string == '\0') return(FALSE);
pattern++;
string++;
break;
case '*':
for( ; ; ) {
switch(*++pattern) {
case '\0':
case ':':
return(TRUE);
case '?':
if(*string == '\0') return(FALSE);
string++;
continue;
case '*':
continue;
default:
break;
}
break;
}
for( ; ; ) {
string = strchr(string,*pattern);
if(string == NULL) return(FALSE);
if(match_aux(pattern,string)) return(TRUE);
string++;
}
default:
if(*pattern != *string) return(FALSE);
string++;
pattern++;
}
}
}
static int match(char *pattern,char *string)
{
while(*pattern != '\0') {
if(match_aux(pattern,string)) return(TRUE);
pattern = strchr(pattern,':');
if(pattern == NULL) return(FALSE);
pattern++;
}
return(FALSE);
}
GrTextOption *GrFindBestFont(int width,int height,int magnify,
char *family,GrTextOption *where)
{
GrFont *f;
int error = TRUE;
int found = (-1);
int ii,minerr;
if(!loaded && !load_fontDB()) return(NULL);
for(f = fontDB,ii = 0; ii < DBsize; f++,ii++) {
if((f->fnt_height <= height) &&
(!f->fnt_isfixed || (f->fnt_width <= width)) &&
(match(family,f->fnt_family))) {
f->FNT_USABLE = TRUE;
error = FALSE;
if((f->fnt_height == height) &&
(!f->fnt_isfixed || (f->fnt_width == width))) {
magnify = FALSE;
found = ii;
break;
}
}
else f->FNT_USABLE = FALSE;
}
if(error) return(NULL);
if(found < 0) {
minerr = 32000;
for(f = fontDB,ii = 0; ii < DBsize; f++,ii++) {
if(!f->FNT_USABLE) continue;
if(!magnify) {
error = height - f->fnt_height;
if(f->fnt_isfixed) error += width - f->fnt_width;
}
else {
int magn = height / f->fnt_height;
int size = magn * f->fnt_height;
error = (height - size) + (2 * --magn);
if(f->fnt_isfixed) {
magn = width / f->fnt_width;
size = magn * f->fnt_width;
error += (width - size) + (2 * --magn);
}
}
if(error < minerr) {
found = ii;
minerr = error;
}
}
}
f = GrLoadFont(fontDB[found].fnt_name);
if(f == NULL) return(NULL);
if(where == NULL) {
where = _GrMalloc(sizeof(GrTextOption));
if(where == NULL) return(NULL);
}
memset(where,0,sizeof(GrTextOption));
where->txo_font = f;
if(!magnify) {
where->txo_xmag = 1;
where->txo_ymag = 1;
}
else {
where->txo_ymag = height / f->fnt_height;
where->txo_xmag = f->fnt_isfixed ?
width / f->fnt_width :
where->txo_ymag;
}
return(where);
}